local nn_rule                 = require "niuniu.nn_rule"
local error_code              = require "error_code"
local constant                = require "constant"
local table_def               = require "table_def"
local cards_com                   = require "cards"
local table_insert            = table.insert
local table_sort              = table.sort
local table_remove            = table.remove
local math_floor              = math.floor
local table_unpack            = table.unpack
local math_random             = math.random
local string_format           = string.format

local GAME_STATUS_INIT        = 0    --鍒濆鍖栫姸鎬�
local GAME_STATUS_START       = 1    --娓告垙寮�濮�
local GAME_STATUS_GRAB_BANKER = 2
local GAME_STATUS_BET         = 3    --鎶兼敞
local GAME_STATUS_CACL_CATTLE = 4
local GAME_STATUS_OVER        = 5    --缁撴潫鐘舵��

local DEFAULT_CARD_TYPE_TIMES = 3

local BET_ACTION              = "bet_req"
local CACL_CATTLE_ACTION      = "cacl_cattle_req"
local GRAB_BANKER_ACTION      = "grab_banker_req"
local TIME_OUT_ACTION         = 1
local PLAYER_ACTION           = 2

local MT_INDEX                = {}
local M                       = {}

M.BET_ACTION                  = BET_ACTION
M.CACL_CATTLE_ACTION          = CACL_CATTLE_ACTION
M.GRAB_BANKER_ACTION          = GRAB_BANKER_ACTION
M.TIME_OUT_ACTION             = TIME_OUT_ACTION
M.PLAYER_ACTION               = PLAYER_ACTION



--math.randomseed(os.time())


local function copy_table(t)
    local new_t = {}

    for k,v in pairs(t) do
        new_t[k] = v
    end

    return new_t
end

function MT_INDEX:shuffle(swap_times)
    assert(self.game_status == GAME_STATUS_START)

    local cards = self.cards
    local card_count = #cards
    swap_times = card_count or swap_times

    for i = 1, swap_times do
        local n = math_random(1, card_count)
        local m = math_random(1, card_count)

        if n ~= m then
            cards[n], cards[m] = cards[m], cards[n]
        end
    end
end

function MT_INDEX:start_game()
    assert(self.game_status == GAME_STATUS_INIT)

    self.game_status = GAME_STATUS_START
end

function MT_INDEX:get_side_cards_map()
    return self.side_cards_map
end

local function find_best_card_set(self,side_cards_map)
    local side_has_best_cards
    for side,cards in pairs(side_cards_map) do
        if side_has_best_cards then
            local src_tile_list = side_cards_map[side]
            local dst_tile_list = side_cards_map[side_has_best_cards]
            local src_type = nn_rule.get_card_type(src_tile_list,self.sorted_special_card_type_list)
            local dst_type = nn_rule.get_card_type(dst_tile_list,self.sorted_special_card_type_list)

            if nn_rule.compare_card(src_type,src_tile_list,dst_type,dst_tile_list) then
                side_has_best_cards = side
            end
        else
            side_has_best_cards = side
        end
    end

    return side_has_best_cards
end

local function find_worst_card_set(self,side_cards_map)
    local side_has_worst_cards
    for side,cards in pairs(side_cards_map) do
        if side_has_worst_cards then
            local src_tile_list = side_cards_map[side]
            local dst_tile_list = side_cards_map[side_has_worst_cards]
            local src_type = nn_rule.get_card_type(src_tile_list,self.sorted_special_card_type_list)
            local dst_type = nn_rule.get_card_type(dst_tile_list,self.sorted_special_card_type_list)

            if not nn_rule.compare_card(src_type,src_tile_list,dst_type,dst_tile_list) then
                side_has_worst_cards = side
            end
        else
            side_has_worst_cards = side
        end
    end

    return side_has_worst_cards
end

local function get_random_side_except(side_cards_map, except_side)
    local sides = {}
    for side, _ in pairs(side_cards_map) do
        if side ~= except_side then
            table_insert(sides, side)
        end
    end
    return sides[math_random(1, #sides)]
end

function MT_INDEX:get_game_type()
    return 2
end

function MT_INDEX:deal(special_uid,will_get_best_cards,self_table_pattern)
 --   dbglog("deal:", tostring(special_uid), tostring(will_get_best_cards), tostring(self_table_pattern))

    assert(self.game_status == GAME_STATUS_START)
    local cards = self.cards
    local side_cards_map = self.side_cards_map
    local sort_side_cards_map = self.sort_side_cards_map

    for uid, player_data in pairs(self.player_data_map) do
        local card_list = {}
        local side = player_data.side

        side_cards_map[side] = card_list
        
        for i = 1, constant.NN_MAX_CARDS_COUNT do
            table_insert(card_list, assert(table_remove(self.cards)))
        end

        sort_side_cards_map[side] = copy_table(card_list)
        nn_rule.sort_card_list(sort_side_cards_map[side])
    --    dbglog("=============uid side",uid,side)
    end

   --[[] for k = 1, self.max_side_num do
        local card_list = {}
        side_cards_map[k] = card_list
        
        for i = 1, constant.NN_MAX_CARDS_COUNT do
            table_insert(card_list, assert(table_remove(self.cards)))
        end

        sort_side_cards_map[k] = copy_table(card_list)
        nn_rule.sort_card_list(sort_side_cards_map[k])
    end--]]

    
    if special_uid then
        local player_data = assert(self.player_data_map[special_uid])
        local side = assert(player_data.side)

        local side_has_best_cards = find_best_card_set(self,sort_side_cards_map)
        local side_has_worst_cards = find_worst_card_set(self,sort_side_cards_map)
        if will_get_best_cards then
            if side_has_best_cards ~= side then
          --      dbglog("=============11111best card")
                side_cards_map[side_has_best_cards],side_cards_map[side] = side_cards_map[side],side_cards_map[side_has_best_cards]
                sort_side_cards_map[side_has_best_cards],sort_side_cards_map[side] = sort_side_cards_map[side],sort_side_cards_map[side_has_best_cards]
            end
        else
            if self_table_pattern ~= 2 then     --不拿最大牌
                if side_has_best_cards == side then
              --      dbglog("==========111111not best card")
                    local random_side = get_random_side_except(side_cards_map,side)
                    side_cards_map[random_side],side_cards_map[side] = side_cards_map[side],side_cards_map[random_side]
                    sort_side_cards_map[random_side],sort_side_cards_map[side] = sort_side_cards_map[side],sort_side_cards_map[random_side]
                end
            else        --拿最小牌
            --    dbglog("=============11111worst card",side_has_worst_cards,side)
                if side_has_worst_cards ~= side then
                    side_cards_map[side_has_worst_cards],side_cards_map[side] = side_cards_map[side],side_cards_map[side_has_worst_cards]
                    sort_side_cards_map[side_has_worst_cards],sort_side_cards_map[side] = sort_side_cards_map[side],sort_side_cards_map[side_has_worst_cards]
                end
            end
        end
    end
  --  print("================111111",cards_com.card_list_to_str_kp(side_cards_map))
end

function MT_INDEX:set_sorted_special_card_type_list(card_type_times_map)
    self.sorted_special_card_type_list = {}

    for card_type, times in pairs(card_type_times_map) do
        table_insert(self.sorted_special_card_type_list, card_type)
    end

    table_sort(self.sorted_special_card_type_list)
end

function MT_INDEX:init(max_side_num, card_type_times_map, sorted_can_bet_times_list, cost, dizhu, game_type, sorted_can_push_times_list)
    local make_card_id = nn_rule.make_card_id
    local cards = {}

    for i = 1, 13 do 
        for j = 1, 4 do
            table_insert(cards, make_card_id(j, i))
        end
    end

    self.game_status = GAME_STATUS_INIT
    self.cards = cards
    self.side_cards_map = {}
    self.sort_side_cards_map = {}
    self.player_data_map = {}
    self.game_result = {}
    self.game_result.bet_result_map = {}
    self.game_result.pay_fee_map = {}
    self.game_result.action_record_map = {}

    self.banker_info = { banker_times = 0, banker_uid = 0 }
    self.game_result.game_valid = false
    self.max_side_num = max_side_num
    self.card_type_times_map = card_type_times_map
    self.sorted_can_bet_times_list = sorted_can_bet_times_list
    self.sorted_can_push_times_list = sorted_can_push_times_list
    self.cost = cost                                                    --鍙拌垂
    self.dizhu = dizhu                                                  --搴曞垎
    self.game_type = game_type
    self.robot_use_pic_num = 0          --当局使用表情的机器人数

    self:set_sorted_special_card_type_list(card_type_times_map)
    self:start_game()
    self:shuffle()

    return true
end

function MT_INDEX:init_player_data(uid, side, curr_own_coins)
    local player_data = {}
    local action_record_map = self.game_result.action_record_map
    local player_data_map = self.player_data_map

    action_record_map[uid] = { win = false }
    player_data_map[uid] = player_data 

    player_data.uid = uid   
    player_data.curr_own_coins = curr_own_coins
    player_data.side = side
    player_data.bet_times = 0
    player_data.banker_times = 0
    player_data.calc_end = false
end

function MT_INDEX:get_banker_and_bet_times(uid)
    if not self.player_data_map then
        return 0,0
    end

    local data = self.player_data_map[uid] or {}
    return (data.banker_times or 0),(data.bet_times or 0)
end

function MT_INDEX:check_player_in_round(uid)
    if not self.player_data_map[uid] then
        return false
    end
    return true
end

function MT_INDEX:grab_banker_action(uid, banker_times, action_type)
   -- dbglog(string_format("uid(%d) banker_times(%d) action_type(%d)", uid, banker_times, action_type))

    if self.game_status ~= GAME_STATUS_GRAB_BANKER then
        return false, error_code.GRAB_BANKER_DEADLINE_ERROR
    end

    if not self:check_player_playing(uid) then
        return false, error_code.NOT_IN_PLAYERING
    end

    local player_data = self.player_data_map[uid]
    player_data.banker_times = banker_times

    if action_type == PLAYER_ACTION then
        self:set_action_had_done(uid, GRAB_BANKER_ACTION)
    end    

    return true
end

function MT_INDEX:grab_banker_complete()
    for uid, player_data in pairs(self.player_data_map) do
        if player_data.banker_times == 0 then
            return false
        end
    end

    return true
end

function MT_INDEX:cacl_cattle_action(uid, action_type)
   -- dbglog(string_format("uid(%d) action_type(%d)", uid, action_type))

    if self.game_status ~= GAME_STATUS_CACL_CATTLE then
        return false, error_code.SHOW_CARD_DEADLINE_ERROR
    end

    if not self:check_player_playing(uid) then
        return false, error_code.NOT_IN_PLAYERING
    end

    local player_data = self.player_data_map[uid]
    player_data.calc_end = true

    if action_type == PLAYER_ACTION then
        self:set_action_had_done(uid, CACL_CATTLE_ACTION)
    end    

    return true
end

function MT_INDEX:set_action_had_done(uid, action_name)
    local action_record_map = self.game_result.action_record_map

    local recode_map = action_record_map[uid]
    recode_map[action_name] = true
end

function MT_INDEX:determine_banker()
    local banker_uid = 0
    local banker_times = 0
    local same_max_times_list = {}
    local tmp_map = {}
    local same_bet_info_list = {}

    for uid, player_data in pairs(self.player_data_map) do
        if player_data.banker_times > 0 then
            table_insert(tmp_map, player_data)
        end
    end

    if #tmp_map > 0 then
        table_sort(tmp_map, function(a, b) return a.banker_times > b.banker_times  end)

        local max_bet_info = tmp_map[1]
        local max_times = max_bet_info.banker_times

        for _, player_data in pairs(tmp_map) do 
            if player_data.banker_times == max_times then
                table_insert(same_bet_info_list, player_data)
                table_insert(same_max_times_list, player_data.uid)
            else
                break
            end
        end

        local i = 1

        if #same_bet_info_list == 1 then
            i = 1
        else
            i = math_random(1, #same_bet_info_list)
        end

        local final_bet_info = same_bet_info_list[i]
        banker_uid = final_bet_info.uid
        banker_times = final_bet_info.banker_times
        self:set_banker_info(banker_uid, banker_times, PLAYER_ACTION)
 --       dbglog(string_format("banker_info(%s) same_max_times_list(%s)", self.banker_info, same_max_times_list))
        return self.banker_info, same_max_times_list
    end

    for uid, player_data in pairs(self.player_data_map) do
        table_insert(same_max_times_list, uid)
    end

    local i = math_random(1, #same_max_times_list)
    banker_uid = same_max_times_list[i]
    banker_times = constant.KPQZ_NN_DEFAULT_BANKER_TIMES
    self:set_banker_info(banker_uid, banker_times, TIME_OUT_ACTION)
    dbglog(string_format("banker_info(%s) same_max_times_list(%s)", self.banker_info, same_max_times_list))
    return self.banker_info, same_max_times_list
end

function MT_INDEX:get_banker_info()
    return self.banker_info
end

function MT_INDEX:get_player_data_map()
    return self.player_data_map
end

function MT_INDEX:is_banker(uid) 
    return uid == self.banker_info.banker_uid
end

function MT_INDEX:set_banker_info(banker_uid, banker_times, action_type)
    if action_type == PLAYER_ACTION then
        self:set_action_had_done(banker_uid, BET_ACTION)
    end

    local player_data = self.player_data_map[banker_uid]
    player_data.banker_times = banker_times

    self.banker_info.banker_uid = banker_uid
    self.banker_info.banker_times = banker_times
end

function MT_INDEX:kpqz_get_bet_times(bet_times, curr_own_coins)
    local banker_times = self.banker_info.banker_times
    local can_bet_times = math_floor((curr_own_coins - self.cost) / (self.dizhu * banker_times * DEFAULT_CARD_TYPE_TIMES))

    if can_bet_times < bet_times then
        local candidate_bet_list = {}

        for _, bet_times in pairs(self.sorted_can_bet_times_list) do
            table_insert(candidate_bet_list, bet_times)
        end

        table_sort(candidate_bet_list, function(times1, times2) return times1 > times2 end)

        for _, candidate_times in pairs(candidate_bet_list) do
            if candidate_times >= can_bet_times then
                return true, candidate_times
            end
        end

        return true, self.sorted_can_bet_times_list[1]   --鍙栨渶灏忕殑鍊嶆暟
    end

    return true, bet_times
end

function MT_INDEX:ordinary_room_get_bet_times(bet_times)
    if bet_times >= self.sorted_can_push_times_list[1] then
        for i, src_times in pairs(self.sorted_can_push_times_list) do
            if bet_times == src_times then
                return true, bet_times
            end
        end
    else
        for i, src_times in pairs(self.sorted_can_bet_times_list) do
            if bet_times == src_times then
                return true, bet_times
            end
        end
    end

    return false, error_code.BET_SELECT_NUMBER_ERROR
end

function MT_INDEX:get_bet_times(bet_times, curr_own_coins)
    local ok = true
    local ret = 0

    -- if self.game_type == table_def.GAME_TYPE_KPQZ_NN then
    --     ok, ret = self:kpqz_get_bet_times(bet_times, curr_own_coins)
    -- elseif self.game_type == table_def.GAME_TYPE_ORDINARY_ROOM_NN then
    --     ok, ret = self:ordinary_room_get_bet_times(bet_times)
    -- else
    --     return false, error_code.ROOMDATA_CONFIG_ERROR
    -- end
    ok, ret = self:kpqz_get_bet_times(bet_times, curr_own_coins)

    if not ok then
        return false, ret
    else
        return true, ret
    end
end

function MT_INDEX:bet_action(uid, bet_times, action_type)
  --  dbglog(string_format("uid(%d) bet_times(%d) action_type(%d)", uid, bet_times, action_type))

    if self.game_status ~= GAME_STATUS_BET then
        return false, error_code.BET_DEADLINE_ERROR
    end

    if uid == self.banker_info.banker_uid then
        return false, error_code.BANKER_CANT_BET_ERROR
    end

    if not self:check_player_playing(uid) then
        return false, error_code.NOT_IN_PLAYERING
    end

    local player_data = self.player_data_map[uid]
    if player_data.bet_times > 0 then
        return false, error_code.HAD_BET_CANT_BET_AGAIN_ERROR
    end
    
    local ok, ret = self:get_bet_times(bet_times, player_data.curr_own_coins)
    if not ok then
        return false, ret
    end

    if action_type == PLAYER_ACTION then
        self:set_action_had_done(uid, BET_ACTION)
    end

--	warlog("MT_INDEX:bet_action------------------", uid, tostring_r(ret))
    --player_data.bet_times = ret
    player_data.bet_times = bet_times
    self.game_result.game_valid = true
    return true
end

function MT_INDEX:is_betting()
	return self.game_status == GAME_STATUS_BET
end

function MT_INDEX:bet_complete()
    for uid, player_data in pairs(self.player_data_map) do
        if uid ~= self.banker_info.banker_uid and player_data.bet_times == 0 then
            return false
        end
    end

    return true
end

function MT_INDEX:do_default_bet()
    local min_bet_times = self.sorted_can_bet_times_list[1]

	local ret = {}
    for uid, player_data in pairs(self.player_data_map) do
        if uid ~= self.banker_info.banker_uid and player_data.bet_times == 0 then            
            local ok,reason = self:bet_action(uid, min_bet_times, TIME_OUT_ACTION)
            print("do_default_bet=====",uid,ok,reason)

			table_insert(ret, {uid=uid, bet_times=min_bet_times})
        end
    end
	return ret
end

function MT_INDEX:check_player_playing(uid)
    local player_data = self.player_data_map[uid]

    if player_data then
        return true
    else
        return false
    end
end

function MT_INDEX:calc_cattle_complete()
    for uid, player_data in pairs(self.player_data_map) do
        if not player_data.calc_end then
            return false
        end
    end

    return true
end

function MT_INDEX:start_grab_banker()
    assert(self.game_status == GAME_STATUS_START)

    self.game_status = GAME_STATUS_GRAB_BANKER
    return true
end

function MT_INDEX:is_grab_banker_time()
    return self.game_status == GAME_STATUS_GRAB_BANKER
end

function MT_INDEX:start_bet()
    assert(self.game_status == GAME_STATUS_GRAB_BANKER)

    self.game_status = GAME_STATUS_BET
    return true
end

function MT_INDEX:start_cacl_cattle()
    assert(self.game_status == GAME_STATUS_BET)

    self.game_status = GAME_STATUS_CACL_CATTLE
    return true
end

function MT_INDEX:is_game_over()
    return self.game_status == GAME_STATUS_OVER
end

function MT_INDEX:get_my_bet_list(uid)
    local player_data = self.player_data_map[uid]
    local bet_info = { uid = uid, bet_times = 0 }

    if not player_data then
        return bet_info
    end

    bet_info.bet_times = player_data.bet_times or 0
    return bet_info
end

function MT_INDEX:get_all_bet_list()
    local ret = {}

    for uid, player_data in pairs(self.player_data_map) do
    	if player_data.bet_times ~= 0 then
        	local bet_info = { uid = uid, bet_times = player_data.bet_times}
        	table_insert(ret, bet_info)
        end
    end
    
    return ret
end    

function MT_INDEX:set_tile_info(uid, type)
    local player_data = self.player_data_map[uid]

    local uid = player_data.uid
    local side = player_data.side
    local uid_bet_result = self.game_result.bet_result_map[uid]

    uid_bet_result.card = self.side_cards_map[side]
    uid_bet_result.type = type
    uid_bet_result.card_times = self.card_type_times_map[type]
end

function MT_INDEX:set_total_times(uid, total_times)
    local uid_bet_result = self.game_result.bet_result_map[uid]
    uid_bet_result.total_times = total_times
end

function MT_INDEX:init_player_result(uid)
    local uid_bet_result = {}
    
    self.game_result.bet_result_map[uid] = uid_bet_result
    uid_bet_result.result_coins = 0
    uid_bet_result.uid = uid   
    uid_bet_result.card = {} 
    uid_bet_result.type = 0  
    uid_bet_result.total_times = 0  

    self.game_result.pay_fee_map[uid] = self.cost

    if uid == self.banker_info.banker_uid then
        uid_bet_result.is_banker = true
    else
        uid_bet_result.is_banker = false
    end
end

function MT_INDEX:set_result_coins(uid, result_coins)
    local uid_bet_result = self.game_result.bet_result_map[uid]
    uid_bet_result.result_coins = result_coins
end

--[[
function MT_INDEX:kpqz_cacl_result()
    self:init_player_result(self.banker_info.banker_uid)  
    local action_record_map = self.game_result.action_record_map    
    local uid_win_coins_map = {}    
    local banker_data = self.player_data_map[self.banker_info.banker_uid]
    local banker_side = banker_data.side
    local banker_cards = self.sort_side_cards_map[banker_side]



errlog("kpqz_cacl_result...")
warlog("banker_info", 			tostring_r(self.banker_info))
warlog("game_result", 			tostring_r(self.game_result))
warlog("player_data_map", 		tostring_r(self.player_data_map))
warlog("sort_side_cards_map", 	tostring_r(self.sort_side_cards_map))



    dbglog(string_format("1------>banker_data(%s) banker_uid(%s) banker_side(%s) banker_cards(%s)", 
        tostring_r(banker_data), tostring_r(self.banker_info.banker_uid), tostring_r(banker_side), tostring_r(banker_cards)))

    local banker_card_type = nn_rule.get_card_type(banker_cards, self.sorted_special_card_type_list)    
    local banker_win_coins = 0
    local banker_lost_coins = 0
    local banker_result_coins = 0

warlog("banker_card_type", banker_card_type, banker_cards)

    self:set_tile_info(self.banker_info.banker_uid, banker_card_type)
    self:set_total_times(self.banker_info.banker_uid, 0)

    for uid, player_data in pairs(self.player_data_map) do        
        if uid ~= self.banker_info.banker_uid then            
            self:init_player_result(uid) 
            local side = player_data.side
            local side_cards = self.sort_side_cards_map[side]
            local action_record = action_record_map[uid]

            dbglog(string_format("2------>player_data(%s) side(%s) side_cards(%s)", 
                tostring_r(player_data), tostring_r(side), tostring_r(side_cards)))

            local side_card_type = nn_rule.get_card_type(side_cards, self.sorted_special_card_type_list)
            local total_times = 1            
            local win = nn_rule.compare_card(side_card_type, side_cards, banker_card_type, banker_cards) 
            action_record.win = win 
             
			--闲家赢
            if win then
                total_times = self.card_type_times_map[side_card_type] * player_data.bet_times * banker_data.banker_times
                local win_coins = total_times * self.dizhu

                if win_coins > player_data.curr_own_coins then
                    win_coins = player_data.curr_own_coins
                end

--warlog("==================================")
--warlog(side_card_type, self.card_type_times_map[side_card_type], player_data.bet_times, banker_data.banker_times)
--warlog(self.banker_info.banker_uid, uid, win_coins, self.dizhu, total_times)




                banker_lost_coins = banker_lost_coins - win_coins
                uid_win_coins_map[uid] = win_coins
            else
				--闲家输
                total_times = self.card_type_times_map[banker_card_type] * player_data.bet_times * banker_data.banker_times
                local lost_coins = total_times * self.dizhu                
                
                if lost_coins > player_data.curr_own_coins then  --闂插閲戝竵涓嶅杈�
                    lost_coins = player_data.curr_own_coins
                end

--warlog("-----------------------------------")
--warlog(banker_card_type, self.card_type_times_map[banker_card_type], player_data.bet_times, banker_data.banker_times)
--warlog(self.banker_info.banker_uid, uid, -lost_coins, self.dizhu, total_times)

                self:set_result_coins(uid, -lost_coins)
                banker_win_coins = banker_win_coins + lost_coins
                --uid_win_coins_map[uid] = -lost_coins
            end

            self:set_tile_info(uid, side_card_type)
            self:set_total_times(uid, total_times)
        end
    end

    banker_result_coins = banker_lost_coins + banker_win_coins

    if banker_result_coins < 0 and math.abs(banker_result_coins) > banker_data.curr_own_coins then --搴勫閲戝竵涓嶅杈�
        banker_result_coins = -banker_data.curr_own_coins
        local banker_can_pay_coins = banker_win_coins + banker_data.curr_own_coins
        local lost_sum_coins = 0

        table_sort(uid_win_coins_map)

        for uid, result_coins in pairs(uid_win_coins_map) do        
            if lost_sum_coins + result_coins > banker_can_pay_coins then
                self:set_result_coins(uid, banker_can_pay_coins - lost_sum_coins)
                break
            else
                self:set_result_coins(uid, result_coins)
            end

            lost_sum_coins = lost_sum_coins + result_coins
        end
    else
        for uid, result_coins in pairs(uid_win_coins_map) do
            self:set_result_coins(uid, result_coins)
        end
    end

    self:set_result_coins(self.banker_info.banker_uid, banker_result_coins)
    return true
end
--]]


function MT_INDEX:kpqz_cacl_result()
    self:init_player_result(self.banker_info.banker_uid)  
    local action_record_map = self.game_result.action_record_map    
    local uid_win_coins_map = {}    
    local banker_data = self.player_data_map[self.banker_info.banker_uid]
    local banker_side = banker_data.side
    local banker_cards = self.sort_side_cards_map[banker_side]



--errlog("kpqz_cacl_result...")
--warlog("banker_info", 			tostring_r(self.banker_info))
--warlog("game_result", 			tostring_r(self.game_result))
--warlog("player_data_map", 		tostring_r(self.player_data_map))
--warlog("sort_side_cards_map", 	cards_com.card_list_to_str_kp(self.sort_side_cards_map))



  --  dbglog(string_format("1------>banker_data(%s) banker_uid(%s) banker_side(%s) banker_cards(%s)", 
  --      tostring_r(banker_data), tostring_r(self.banker_info.banker_uid), tostring_r(banker_side), tostring_r(banker_cards)))

    local banker_card_type = nn_rule.get_card_type(banker_cards, self.sorted_special_card_type_list)    
    local banker_win_coins = 0
    local banker_lost_coins = 0
    local banker_result_coins = 0

--warlog("banker_card_type", banker_card_type, banker_cards)

    self:set_tile_info(self.banker_info.banker_uid, banker_card_type)
    self:set_total_times(self.banker_info.banker_uid, 0)

    for uid, player_data in pairs(self.player_data_map) do        
        if uid ~= self.banker_info.banker_uid then            
            self:init_player_result(uid) 
            local side = player_data.side
            local side_cards = self.sort_side_cards_map[side]
            local action_record = action_record_map[uid]

  --          dbglog(string_format("2------>player_data(%s) side(%s) side_cards(%s)", 
   --             tostring_r(player_data), tostring_r(side), cards_com.cards_to_str(side_cards)))

            local side_card_type = nn_rule.get_card_type(side_cards, self.sorted_special_card_type_list)
            local total_times = 1            
            local win = nn_rule.compare_card(side_card_type, side_cards, banker_card_type, banker_cards) 
            action_record.win = win 
             
			--闲家赢
            if win then
                total_times = self.card_type_times_map[side_card_type] * player_data.bet_times * banker_data.banker_times
                local win_coins = total_times * self.dizhu

                if win_coins > player_data.curr_own_coins then
                    win_coins = player_data.curr_own_coins
                end

--warlog("==================================")
--warlog(side_card_type, self.card_type_times_map[side_card_type], player_data.bet_times, banker_data.banker_times)
--warlog(self.banker_info.banker_uid, uid, win_coins, self.dizhu, total_times)




                banker_lost_coins = banker_lost_coins - win_coins
                uid_win_coins_map[uid] = win_coins
            else
				--闲家输
                total_times = self.card_type_times_map[banker_card_type] * player_data.bet_times * banker_data.banker_times
                local lost_coins = total_times * self.dizhu                
                
                if lost_coins > player_data.curr_own_coins then  --闂插閲戝竵涓嶅杈�
                    lost_coins = player_data.curr_own_coins
                end

--warlog("-----------------------------------")
--warlog(banker_card_type, self.card_type_times_map[banker_card_type], player_data.bet_times, banker_data.banker_times)
--warlog(self.banker_info.banker_uid, uid, -lost_coins, self.dizhu, total_times)

                --self:set_result_coins(uid, -lost_coins)
                banker_win_coins = banker_win_coins + lost_coins
                uid_win_coins_map[uid] = -lost_coins
            end

            self:set_tile_info(uid, side_card_type)
            self:set_total_times(uid, total_times)
        end
    end

    banker_result_coins = banker_lost_coins + banker_win_coins

--[[
    if banker_result_coins < 0 and math.abs(banker_result_coins) > banker_data.curr_own_coins then --搴勫閲戝竵涓嶅杈�
        banker_result_coins = -banker_data.curr_own_coins
        local banker_can_pay_coins = banker_win_coins + banker_data.curr_own_coins
        local lost_sum_coins = 0

        table_sort(uid_win_coins_map)

        for uid, result_coins in pairs(uid_win_coins_map) do        
            if lost_sum_coins + result_coins > banker_can_pay_coins then
                self:set_result_coins(uid, banker_can_pay_coins - lost_sum_coins)
                break
            else
                self:set_result_coins(uid, result_coins)
            end

            lost_sum_coins = lost_sum_coins + result_coins
        end
    else
        for uid, result_coins in pairs(uid_win_coins_map) do
            self:set_result_coins(uid, result_coins)
        end
    end

    self:set_result_coins(self.banker_info.banker_uid, banker_result_coins)
    return true
--]]

	if banker_result_coins > 0 then	
		if banker_result_coins > banker_data.curr_own_coins then
			for uid, result_coins in pairs(uid_win_coins_map) do
				--其他玩家实际结算=本应结算金币*(庄家持有金币/桌面结算金币)，无论输赢
				uid_win_coins_map[uid] = math_floor( result_coins * ( banker_data.curr_own_coins / banker_result_coins ) )
			end
	
			--1.1.1庄家只赢得跟自己等量的金币
			banker_result_coins = banker_data.curr_own_coins
		end 	
	elseif banker_result_coins < 0 then 
		if -banker_result_coins > banker_data.curr_own_coins then
			for uid, result_coins in pairs(uid_win_coins_map) do
				uid_win_coins_map[uid] = math_floor( result_coins * ( banker_data.curr_own_coins / -banker_result_coins ) )	
			end

			banker_result_coins = -banker_data.curr_own_coins
		end 
	end


	for uid, result_coins in pairs(uid_win_coins_map) do
		self:set_result_coins(uid, result_coins)
	end
	
	self:set_result_coins(self.banker_info.banker_uid, banker_result_coins)
	
	return true
end

function MT_INDEX:get_table_dizhu()
    return self.dizhu
end

function MT_INDEX:get_all_player_tile_list()
    local tile_map = {}
    for uid,player_data in pairs(self.player_data_map) do        
        local side = player_data.side
        local side_cards = self.sort_side_cards_map[side]
        tile_map[uid] = {side = side,cards = side_cards}
    end

    return tile_map
end
function MT_INDEX:ordinary_room_cacl_result()
    self:init_player_result(self.banker_info.banker_uid)      
    local action_record_map = self.game_result.action_record_map
    local uid_win_coins_map = {}    
    local banker_data = self.player_data_map[self.banker_info.banker_uid]
    local banker_side = banker_data.side
    local banker_cards = self.sort_side_cards_map[banker_side]
    local banker_card_type = nn_rule.get_card_type(banker_cards, self.sorted_special_card_type_list)   

  --  dbglog(string_format("1------>banker_data(%s) banker_uid(%s) banker_side(%s) banker_cards(%s)", 
   --     tostring_r(banker_data), tostring_r(self.banker_info.banker_uid), tostring_r(banker_side), tostring_r(banker_cards))) 
    
    local banker_win_coins = 0
    local banker_lost_coins = 0
    local banker_result_coins = 0

    self:set_tile_info(self.banker_info.banker_uid, banker_card_type)
    self:set_total_times(self.banker_info.banker_uid, 0)

    for uid, player_data in pairs(self.player_data_map) do        
        if uid ~= self.banker_info.banker_uid then
            self:init_player_result(uid) 
            local side = player_data.side
            local action_record = action_record_map[uid]

        --    dbglog(string_format("2------>player_data(%s) side(%s) side_cards(%s)", 
         --       tostring_r(player_data), tostring_r(side), tostring_r(side_cards)))

            local side_cards = self.sort_side_cards_map[side]
            local side_card_type = nn_rule.get_card_type(side_cards, self.sorted_special_card_type_list)
            local total_times = 1            
            local win = nn_rule.compare_card(side_card_type, side_cards, banker_card_type, banker_cards)  
            action_record.win = win
             
			--warlog("zzzzzzzz", tostring_r(player_data) )

            if win then
				--warlog("--------------------------------------")
				--warlog(side_card_type, tostring_r(self.card_type_times_map), player_data.bet_times, tostring_r(banker_data.banker_times))
				--warlog("======================================")


                total_times = self.card_type_times_map[side_card_type] * player_data.bet_times * banker_data.banker_times
                local win_coins = total_times * self.dizhu

                banker_lost_coins = banker_lost_coins - win_coins
                uid_win_coins_map[uid] = win_coins
            else
				--warlog("--------------------------------------")
				--warlog(banker_card_type, tostring_r(self.card_type_times_map), tostring_r(player_data.bet_times), tostring_r( banker_data.banker_times ))
				--warlog("======================================")

                total_times = self.card_type_times_map[banker_card_type] * player_data.bet_times * banker_data.banker_times
                local lost_coins = total_times * self.dizhu                

                self:set_result_coins(uid, -lost_coins)
                banker_win_coins = banker_win_coins + lost_coins
            end

            self:set_tile_info(uid, side_card_type)
            self:set_total_times(uid, total_times)
        end
    end

    for uid, result_coins in pairs(uid_win_coins_map) do
        self:set_result_coins(uid, result_coins)
    end

    banker_result_coins = banker_lost_coins + banker_win_coins
    self:set_result_coins(self.banker_info.banker_uid, banker_result_coins)
    return true
end

function MT_INDEX:cacl_result()
    return self:kpqz_cacl_result()

    -- if self.game_type == table_def.GAME_TYPE_KPQZ_NN then
        --return self:kpqz_cacl_result()
    -- elseif self.game_type == table_def.GAME_TYPE_ORDINARY_ROOM_NN then
    --     return self:ordinary_room_cacl_result()
    -- end
end

function MT_INDEX:judge_result()
    assert(self.game_status == GAME_STATUS_CACL_CATTLE)
    self:cacl_result()
    
    self.game_status = GAME_STATUS_OVER
    return true
end

function MT_INDEX:get_game_result()
    assert(self.game_status == GAME_STATUS_OVER)

    return self.game_result
end

local function compare(a,b)
    if nn_rule.compare_card(a.card_type,a.cards,b.card_type,b.cards) then
        return true
    end

    return false
end

local function get_sort_player_cards_power_list(self,player_list)
    local player_cards_power_list = {}

    for _,uid in pairs(player_list) do
        local player_data = self.player_data_map[uid]
        local player_cards = copy_table(self.sort_side_cards_map[player_data.side])
        local player_cards_type = nn_rule.get_card_type(player_cards,self.sorted_special_card_type_list)
        table_insert(player_cards_power_list,{uid = uid,
        card_type = player_cards_type,cards = player_cards})
    end

 --  print_r(player_cards_power_list)
    --排序
    table_sort(player_cards_power_list,compare)

    return player_cards_power_list
end

local function get_new_index(self,player_cards_power_list,banker_index,win)
    local get_total_number = function(index)
        local total_number = 0
        for i=1,#player_cards_power_list do
            if i ~= index then
                local uid = player_cards_power_list[i].uid
                local cards_power = player_cards_power_list[i]
                local player_data = self.player_data_map[uid]
                local bet_times = player_data.bet_times
                local banker_power = player_cards_power_list[index]

                if i < index then
                    total_number = total_number - bet_times * self.card_type_times_map[cards_power.card_type]
                elseif i > index then
                    total_number = total_number + bet_times * self.card_type_times_map[banker_power.card_type]
                end
            end
        end
        return total_number
    end

    local new_index = banker_index
    local total_number = get_total_number(new_index)
    if win then
        while total_number <= 0 do
            player_cards_power_list[new_index],player_cards_power_list[new_index - 1] = 
            player_cards_power_list[new_index - 1],player_cards_power_list[new_index]
            new_index = new_index - 1
            total_number = get_total_number(new_index)
        end
    else
        while total_number > 0 do
            player_cards_power_list[new_index],player_cards_power_list[new_index + 1] = 
            player_cards_power_list[new_index + 1],player_cards_power_list[new_index]
            new_index = new_index + 1
            total_number = get_total_number(new_index)
        end
    end
    return new_index
end

local function get_first_four_cards(card_list)
    if #card_list < 5 then
        errlog("errror to get_first_four_cards",tostring_r(card_list))
    end

    local tmp_card_list = {}
    for i = 1, 4 do
        table_insert(tmp_card_list,card_list[i])
    end
    return tmp_card_list
end

local function put_cards_map(card_number_set,card_id)
    local number = card_id % 100
    if number == 14 then
        number = 1 --拼三张A是14，牛牛为1
    end

    if number > 10 then
        number = 10
    end

    local t = card_number_set[number]
    if not t then t = {} card_number_set[number] = t end
    table_insert(t,card_id)
end

local function cal_banker_result(self,player_cards_power_list,index)
    local total_number = 0
    for i=1,#player_cards_power_list do
        if i ~= index then
            local uid = player_cards_power_list[i].uid
            local cards_power = player_cards_power_list[i]
            local player_data = self.player_data_map[uid]
            local bet_times = player_data.bet_times
            local banker_power = player_cards_power_list[index]

            if i < index then
                total_number = total_number - bet_times * self.card_type_times_map[cards_power.card_type]
            elseif i > index then
                total_number = total_number + bet_times * self.card_type_times_map[banker_power.card_type]
            end
        end
    end
  --  print("=========index",index,total_number)
    return total_number > 0
end

local function compare_card(src_type, src_tile_list, dst_type, dst_tile_list)
    local sort_src_tile_list = copy_table(src_tile_list)
    nn_rule.sort_card_list(sort_src_tile_list) 

    local sort_dst_tile_list = copy_table(dst_tile_list)
    nn_rule.sort_card_list(sort_dst_tile_list)
    
    return nn_rule.compare_card(src_type, sort_src_tile_list, dst_type, sort_dst_tile_list)
end

function MT_INDEX:control_banker_result(player_list,win)
    dbglog("control_banker_result===111",win,tostring_r(player_list))
    if self.game_status ~= GAME_STATUS_BET then
        errlog("game status is not same")
        return
    end
    if #player_list <= 1 then
        return
    end
    
    local player_cards_power_list = get_sort_player_cards_power_list(self,player_list)
  --  print_r(player_cards_power_list)
    local banker_index = 1
    for index,cards_power in pairs(player_cards_power_list) do
        if cards_power.uid == self.banker_info.banker_uid then
            banker_index = index
            break
        end
    end

    local new_index = get_new_index(self,player_cards_power_list,banker_index,win)
   -- print("control_banker_result===222",new_index,banker_index)
    if new_index ~= banker_index then
        --[[local card_list = nn_rule.get_cards(self.cards,player_cards_power_list[new_index - 1],
        player_cards_power_list[new_index + 1],self.sorted_special_card_type_list) 
        if not card_list or #card_list ~= 5 then
            return
        end
        local sort_list = copy_table(card_list)
        nn_rule.sort_card_list(sort_list)

        local banker_data = self.player_data_map[self.banker_info.banker_uid]
        self.side_cards_map[banker_data.side] = card_list

        self.sort_side_cards_map[banker_data.side] = sort_list]]

        local min_cards_power = player_cards_power_list[new_index + 1]
        local max_cards_power = player_cards_power_list[new_index - 1]
        local cards_map = nn_rule.make_card_number_set(self.cards)
     --   print("left_cards_map========",tostring_r(cards_map))
        --获取换第5张牌后最大的牌型和最小牌型
        local max_card_type,max_value,min_card_type,min_value
        local banker_data = self.player_data_map[self.banker_info.banker_uid]
        local banker_card_list = self.side_cards_map[banker_data.side]
        local first_four_cards = get_first_four_cards(banker_card_list)
        local change_list = {}
        if win then --如果要庄家赢,只要牌型大于min_cards_power就符合要求
            for i = 1,10 do
                if cards_map[i] and #cards_map[i] > 0 then
                    local card_id = 100 + i
                    local test_card_list = copy_table(first_four_cards)
                    table_insert(test_card_list,card_id)
                    local card_type = nn_rule.get_card_type(test_card_list,self.sorted_special_card_type_list)
                    if not max_card_type or card_type > max_card_type then
                        max_card_type = card_type
                        max_value = i
                    end

                    if compare_card(card_type,test_card_list,min_cards_power.card_type,min_cards_power.cards) then
                        table_insert(change_list,i)
                    end
                end
            end
        else    --如果要庄家输,只要牌型小于min_cards_power就符合要求
            for i = 1,10 do
                if cards_map[i] and #cards_map[i] > 0 then
                    local card_id = 100 + i
                    local test_card_list = copy_table(first_four_cards)
                    table_insert(test_card_list,card_id)
                    local card_type = nn_rule.get_card_type(test_card_list,self.sorted_special_card_type_list)
                    if not min_card_type or card_type < min_card_type then
                        min_card_type = card_type
                        min_value = i
                    end

                    if compare_card(max_cards_power.card_type,max_cards_power.cards,card_type,test_card_list) then
                        table_insert(change_list,i)
                    end
                end
            end
        end

        local change_fifth_card = function(card_list,card_id,player_side)
            local old_card_id = table_remove(card_list)
            table_insert(card_list,card_id)
            put_cards_map(cards_map,old_card_id)

            local sort_list = copy_table(card_list)
            nn_rule.sort_card_list(sort_list) 
            self.sort_side_cards_map[player_side] = sort_list
         --   print("change player card succ============",card_id,old_card_id,tostring_r(card_list))
        end
      --  print("change_list is ",max_card_type,max_value,tostring_r(change_list))
        if #change_list > 0 then
      --      print("11111111111")
            --随机取一张符合要求的牌替换庄家的第五张牌
            local card_value = change_list[math_random(1,#change_list)]
            local card_id = table_remove(cards_map[card_value])
            change_fifth_card(banker_card_list,card_id,banker_data.side)
        else
            --没有符合要求的牌型，如果控制庄家赢将庄家换成最大牌型，控制庄家输则将庄家换成最小牌型
            if win and max_value then
       --         print("2222222222222222")
                local card_id = table_remove(cards_map[max_value])
                change_fifth_card(banker_card_list,card_id,banker_data.side)
            elseif not win and min_value then
          --      print("3333333333333333")
                local card_id = table_remove(cards_map[min_value])
                change_fifth_card(banker_card_list,card_id,banker_data.side)
            end

            local banker_card_type = nn_rule.get_card_type(banker_card_list,self.sorted_special_card_type_list)
            local change_count = 0
            while true do
                change_count = change_count + 1
                --重新排序一次
                local new_player_cards_power_list = get_sort_player_cards_power_list(self,player_list)
                local new_banker_index = 1
                for index,cards_power in pairs(new_player_cards_power_list) do
                    if cards_power.uid == self.banker_info.banker_uid then
                        new_banker_index = index
                        break
                    end
                end

                local result = cal_banker_result(self,new_player_cards_power_list,new_banker_index)
                if (result and win) or (not result and not win) or change_count > 4 then 
                    break
                end

                --选择大于庄家并且下注倍数最高的玩家
                local max_bet_uid,bet_coins
                if win then
                    for i = 1,new_banker_index - 1 do
                        local uid = new_player_cards_power_list[i].uid
                        local player_data = self.player_data_map[uid]
                        if not bet_coins or player_data.bet_times > bet_coins then
                            bet_coins = player_data.bet_times
                            max_bet_uid = uid
                        end
                    end
                else
                    for i = #new_player_cards_power_list,new_banker_index + 1,-1 do
                        local uid = new_player_cards_power_list[i].uid
                        local player_data = self.player_data_map[uid]
                        if not bet_coins or player_data.bet_times > bet_coins then
                            bet_coins = player_data.bet_times
                            max_bet_uid = uid
                        end
                    end
                end
                if not max_bet_uid then
                    break
                end
                
                local player_uid = max_bet_uid
                local player_data = self.player_data_map[player_uid]
                local player_cards = self.side_cards_map[player_data.side]
                local player_card_type = nn_rule.get_card_type(player_cards,self.sorted_special_card_type_list)

                --换选择出的玩家的第五张牌
                local new_max_card_type,new_max_value,new_min_card_type,new_min_value
                local first_four_cards = get_first_four_cards(player_cards)
                local new_change_list = {}
                if win then 
                    for i = 1,10 do
                        if cards_map[i] and #cards_map[i] > 0 then
                            local card_id = 100 + i
                            local test_card_list = copy_table(first_four_cards)
                            table_insert(test_card_list,card_id)
                            local card_type = nn_rule.get_card_type(test_card_list,self.sorted_special_card_type_list)
                            if not max_card_type or card_type > max_card_type then
                                max_card_type = card_type
                                max_value = i
                            end
                            
                            --如果要庄家赢,玩家的牌需要比庄家小
                            if compare_card(banker_card_type,banker_card_list,card_type,test_card_list) then
                                table_insert(new_change_list,i)
                            end
                        end
                    end
                else    
                    for i = 1,10 do
                        if cards_map[i] and #cards_map[i] > 0 then
                            local card_id = 100 + i
                            local test_card_list = copy_table(first_four_cards)
                            table_insert(test_card_list,card_id)
                            local card_type = nn_rule.get_card_type(test_card_list,self.sorted_special_card_type_list)
                            if not min_card_type or card_type < min_card_type then
                                min_card_type = card_type
                                min_value = i
                            end

                            --如果要庄家输,玩家牌型需要比庄家大
                            if compare_card(card_type,test_card_list,banker_card_type,banker_card_list) then
                                table_insert(new_change_list,i)
                            end
                        end
                    end
                end

                if #new_change_list > 0 then
                    --随机取一张符合要求的牌替换庄家的第五张牌
                    local card_value = new_change_list[math_random(1,#new_change_list)]
                    local card_id = table_remove(cards_map[card_value])
                    change_fifth_card(player_cards,card_id,player_data.side)
                else
                    --没有符合要求的牌型，如果控制庄家赢将庄家换成最大牌型，控制庄家输则将庄家换成最小牌型
                    if win and new_max_value then
                        local card_id = table_remove(cards_map[new_max_value])
                        change_fifth_card(player_cards,card_id,player_data.side)
                    elseif not win and new_min_value then
                        local card_id = table_remove(cards_map[new_min_value])
                        change_fifth_card(player_cards,card_id,player_data.side)
                    end
                end
            end
        end
    end
end

function MT_INDEX:control_player_result(uid,win)
 --   dbglog("control_player_result====================",win,uid)
    if self.game_status ~= GAME_STATUS_BET then
        errlog("game status is not same")
        return
    end

    local banker_data = self.player_data_map[self.banker_info.banker_uid]
    local banker_cards = self.side_cards_map[banker_data.side]
    local banker_card_type = nn_rule.get_card_type(banker_cards,self.sorted_special_card_type_list)

    local player_data = self.player_data_map[uid]
    local player_cards = self.side_cards_map[player_data.side]
    local player_card_type = nn_rule.get_card_type(player_cards,self.sorted_special_card_type_list)
    local first_four_cards = get_first_four_cards(player_cards)

    local cards_map = nn_rule.make_card_number_set(self.cards)
   -- dbglog("===uid cards,banker_cards",tostring_r(player_cards),tostring_r(banker_cards))

    local change_fifth_card = function(card_list,card_id,player_side)
        local old_card_id = table_remove(card_list)
        table_insert(card_list,card_id)
        put_cards_map(cards_map,old_card_id)

        local sort_list = copy_table(card_list)
        nn_rule.sort_card_list(sort_list) 
        self.sort_side_cards_map[player_side] = sort_list
   --     print("change player card succ============",card_id,old_card_id,tostring_r(card_list))
    end

    if win then
        if compare_card(player_card_type,player_cards,banker_card_type,banker_cards) then
            return
        end
        local change_list = {}
        local max_card_type,max_value
        for i = 1,10 do
            if cards_map[i] and #cards_map[i] > 0 then
                local card_id = 100 + i
                local test_card_list = copy_table(first_four_cards)
                table_insert(test_card_list,card_id)
                local card_type = nn_rule.get_card_type(test_card_list,self.sorted_special_card_type_list)
                if not max_card_type or card_type > max_card_type then
                    max_card_type = card_type
                    max_value = i
                end

                if compare_card(card_type,test_card_list,banker_card_type,banker_cards) then
                    table_insert(change_list,i)
                end
            end
        end
      --  print("ttttttttttt",max_card_type,max_value,tostring_r(change_list))

        if #change_list > 0 then
            --随机取一张符合要求的牌替换玩家的第五张牌
            local card_value = change_list[math_random(1,#change_list)]
            local card_id = table_remove(cards_map[card_value])
            change_fifth_card(player_cards,card_id,player_data.side)

        elseif max_value then
            --将玩家牌设置为最大，再换庄家牌
            local card_id = table_remove(cards_map[max_value])
            change_fifth_card(player_cards,card_id,player_data.side)
            
            --更换庄家牌型
            local new_player_card_type = nn_rule.get_card_type(player_cards,self.sorted_special_card_type_list)
            local banker_change_list = {}
            local banker_min_card_type,banker_min_value
            local banker_four_cards = get_first_four_cards(banker_cards)
            for i = 1,10 do
                if cards_map[i] and #cards_map[i] > 0 then
                    local card_id = 100 + i
                    local test_card_list = copy_table(banker_four_cards)
                    table_insert(test_card_list,card_id)
                    local card_type = nn_rule.get_card_type(test_card_list,self.sorted_special_card_type_list)
                    if not banker_min_card_type or card_type < banker_min_value then
                        banker_min_card_type = card_type
                        banker_min_value = i
                    end
    
                    if compare_card(new_player_card_type,player_cards,card_type,test_card_list) then
                        table_insert(banker_change_list,i)
                    end
                end
            end

            if #banker_change_list > 0 then
                --随机取一张符合要求的牌替换庄家的第五张牌
                local card_value = banker_change_list[math_random(1,#banker_change_list)]
                local card_id = table_remove(cards_map[card_value])
            
                change_fifth_card(banker_cards,card_id,banker_data.side)
            elseif banker_min_value then
                local card_id = table_remove(cards_map[banker_min_value])
                change_fifth_card(banker_cards,card_id,banker_data.side)
            end
        end

    else
        --控制玩家输
        if compare_card(banker_card_type,banker_cards,player_card_type,player_cards) then
            return
        end

        local change_list = {}
        local min_card_type,min_value
        for i = 1,10 do
            if cards_map[i] and #cards_map[i] > 0 then
                local card_id = 100 + i
                local test_card_list = copy_table(first_four_cards)
                table_insert(test_card_list,card_id)
                local card_type = nn_rule.get_card_type(test_card_list,self.sorted_special_card_type_list)
                if not min_card_type or card_type < min_card_type then
                    min_card_type = card_type
                    min_value = i
                end

                if compare_card(banker_card_type,banker_cards,card_type,test_card_list) then
                    table_insert(change_list,i)
                end
            end
        end
     --   print("tttttttttttttttt",min_value,tostring_r(change_list))
        if #change_list > 0 then
            --随机取一张符合要求的牌替换玩家的第五张牌
            local card_value = change_list[math_random(1,#change_list)]
            local card_id = table_remove(cards_map[card_value])
            change_fifth_card(player_cards,card_id,player_data.side)
        elseif min_value then
            --将玩家牌设置为最小，再换庄家牌
            local card_id = table_remove(cards_map[min_value])
            change_fifth_card(player_cards,card_id,player_data.side)
            
            --更换庄家牌型
            local new_player_card_type = nn_rule.get_card_type(player_cards,self.sorted_special_card_type_list)
            local banker_change_list = {}
            local banker_max_card_type,banker_max_value
            local banker_four_cards = get_first_four_cards(banker_cards)
            for i = 1,10 do
                if cards_map[i] and #cards_map[i] > 0 then
                    local card_id = 100 + i
                    local test_card_list = copy_table(banker_four_cards)
                    table_insert(test_card_list,card_id)
                    local card_type = nn_rule.get_card_type(test_card_list,self.sorted_special_card_type_list)
                    if not banker_max_card_type or card_type > banker_max_value then
                        banker_max_card_type = card_type
                        banker_max_value = i
                    end
    
                    if compare_card(card_type,test_card_list,new_player_card_type,player_cards) then
                        table_insert(banker_change_list,i)
                    end
                end
            end

            if #banker_change_list > 0 then
                --随机取一张符合要求的牌替换庄家的第五张牌
                local card_value = banker_change_list[math_random(1,#banker_change_list)]
                local card_id = table_remove(cards_map[card_value])
                change_fifth_card(banker_cards,card_id,banker_data.side)
            elseif banker_max_value then
                local card_id = table_remove(cards_map[banker_max_value])
                change_fifth_card(banker_cards,card_id,banker_data.side)
            end
        end
    end
  --  dbglog("===after change uid cards,banker_cards",tostring_r(player_cards),tostring_r(banker_cards))
end


local function put_cards(cards,card_list)
    --将card_list放入self.cards
    for i=1,#card_list do
        table_insert(cards,card_list[i])
    end
end

--玩家是庄家只能替换闲家机器人的牌
function MT_INDEX:control_robot_result(robot_list,banker_win)
  --  dbglog("control_robot_result==================",banker_win,tostring_r(robot_list))
    if self.game_status ~= GAME_STATUS_BET then
        errlog("game status is not same1122")
        return
    end
    
    if self.game_status ~= GAME_STATUS_BET then
        errlog("game status is not same")
        return
    end
    
    local player_cards_power_list = get_sort_player_cards_power_list(self,robot_list)

    local banker_index = 1
    for index,cards_power in pairs(player_cards_power_list) do
        if cards_power.uid == self.banker_info.banker_uid then
            banker_index = index
            break
        end
    end
    
    local new_index = get_new_index(self,player_cards_power_list,banker_index,banker_win)
  --  print("ssssssss",banker_index,new_index,tostring_r(self.sort_side_cards_map))
    if new_index ~= banker_index then
        if new_index > banker_index then
            for i= banker_index,new_index - 1 do
                local card_list = nn_rule.get_cards(self.cards,nil,
                player_cards_power_list[new_index],self.sorted_special_card_type_list)
                if not card_list or #card_list ~= 5 then
                    return
                end

                local sort_list = copy_table(card_list)
                nn_rule.sort_card_list(sort_list)

                local uid = player_cards_power_list[i].uid
                local player_data = self.player_data_map[uid]
                self.side_cards_map[player_data.side] = card_list
                self.sort_side_cards_map[player_data.side] = sort_list
            end
        elseif new_index < banker_index then
            for i = banker_index,new_index + 1,-1 do
                local card_list = nn_rule.get_cards(self.cards,player_cards_power_list[new_index],nil
                ,self.sorted_special_card_type_list)
                if not card_list or #card_list ~= 5 then
                    return
                end

                local sort_list = copy_table(card_list)
                nn_rule.sort_card_list(sort_list)

                local uid = player_cards_power_list[i].uid
                local player_data = self.player_data_map[uid]
                local old = copy_table(self.side_cards_map[player_data.side])
                put_cards(self.cards,copy_table(self.side_cards_map[player_data.side]))

                self.side_cards_map[player_data.side] = card_list
                self.sort_side_cards_map[player_data.side] = sort_list
            end
        end
    end
end  

function MT_INDEX:robot_can_use_pic(pic_conf)
    if not pic_conf or not pic_conf.select_pic then 
        return 
    end
    if self.robot_use_pic_num >= 2 then --单局最多允许2个机器人使用表情
        return
    end
    local use_rate = pic_conf.use_rate or 0
    local use_pic = pic_conf.select_pic 
    if math_random(1,100) <= pic_conf.use_rate then
        local select_pic = use_pic[math_random(1,#use_pic)]
        local delay_time
        if pic_conf.delay_time then
            delay_time = math_random(pic_conf.delay_time[1],pic_conf.delay_time[2])
        end
        return select_pic,delay_time
    end

    return false
end

function MT_INDEX:add_use_pic_num()
    self.robot_use_pic_num = self.robot_use_pic_num + 1
end

function M.new()
    local o = {}
    return setmetatable(o, { __index = MT_INDEX })
end

return M
